// This file is part of Keepass2Android, Copyright 2025 Philipp Crocoll.
//
//   Keepass2Android is free software: you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation, either version 3 of the License, or
//   (at your option) any later version.
//
//   Keepass2Android is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with Keepass2Android.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using Android.App;
using keepass2android;
using KeePassLib;
using KeePassLib.Security;
using KeePassLib.Serialization;
using Object = Java.Lang.Object;

namespace keepass2android
{
  /// <summary>
  /// Edit mode implementation for AutoOpen entries
  /// </summary>
  public class AutoOpenEdit : EditModeBase
  {
    private const string strVisible = "Visible";
    private const string strEnabled = "Enabled";
    private const string strUiKeyFile = "_ui_KeyFile";
    private const string strUiDatabaseFile = "_ui_DatabaseFile";
    private const string strUiIfDevice = "_ui_IfDevice_";

    public AutoOpenEdit(PwEntry entry)
    {

    }

    public override bool IsVisible(string fieldKey)
    {
      if (fieldKey == PwDefs.TitleField
          || fieldKey == PwDefs.PasswordField
          || fieldKey == strVisible
          || fieldKey == strEnabled
          || fieldKey.StartsWith("_ui_"))
      {
        return true;
      }
      return false;
    }

    public override IEnumerable<string> SortExtraFieldKeys(IEnumerable<string> keys)
    {
      return keys.OrderBy(s =>
      {
        if (s == strUiDatabaseFile) return 1;
        if (s == strEnabled) return 2;

        if (s == strUiKeyFile) return 10000;
        if (s == strVisible) return 10001;
        return 10;

      }).ThenBy(s => s);

    }

    public override bool ShowAddAttachments
    {
      get { return false; }
    }

    public override bool ShowAddExtras
    {
      get { return false; }
    }

    public override string GetTitle(string key)
    {
      if (key == strVisible)
        return LocaleManager.LocalizedAppContext.GetString(Resource.String.Visible_title);
      if (key == strEnabled)
        return LocaleManager.LocalizedAppContext.GetString(Resource.String.child_db_Enabled_title);
      if (key == strUiKeyFile)
        return LocaleManager.LocalizedAppContext.GetString(Resource.String.keyfile_heading);
      if (key == strUiDatabaseFile)
        return LocaleManager.LocalizedAppContext.GetString(Resource.String.database_file_heading);
      if (key.StartsWith(strUiIfDevice))
      {
        return LocaleManager.LocalizedAppContext.GetString(Resource.String.if_device_text, new Object[] { key.Substring(strUiIfDevice.Length) });
      }
      return key;
    }

    public override string GetFieldType(string key)
    {
      if ((key == strEnabled)
          || key == strVisible
          || key.StartsWith(strUiIfDevice))
        return "bool";

      if ((key == strUiDatabaseFile)
          || (key == strUiKeyFile))
        return "file";

      return "";
    }

    public override void InitializeEntry(PwEntry entry)
    {
      base.InitializeEntry(entry);
      if (!entry.Strings.Exists(strVisible))
      {
        entry.Strings.Set(strVisible, new ProtectedString(false, "true"));
      }
      if (!entry.Strings.Exists(strEnabled))
      {
        entry.Strings.Set(strEnabled, new ProtectedString(false, "true"));
      }
      var autoExecItem = KeeAutoExecExt.MakeAutoExecItem(App.Kp2a.CurrentDb.KpDatabase, entry, 0);
      IOConnectionInfo ioc;
      if (!KeeAutoExecExt.TryGetDatabaseIoc(autoExecItem, out ioc))
        ioc = IOConnectionInfo.FromPath(entry.Strings.ReadSafe(PwDefs.UrlField));
      string path = ioc.Path;
      try
      {
        var filestorage = App.Kp2a.GetFileStorage(ioc);
        if (filestorage != null)
        {
          path = filestorage.IocToPath(ioc);
        }
      }
      catch (NoFileStorageFoundException)
      {

      }


      entry.Strings.Set(strUiDatabaseFile, new ProtectedString(false, path));
      entry.Strings.Set(strUiKeyFile, new ProtectedString(false, entry.Strings.ReadSafe(PwDefs.UserNameField)));

      var devices =
          KeeAutoExecExt.GetIfDevice(KeeAutoExecExt.MakeAutoExecItem(App.Kp2a.CurrentDb.KpDatabase, entry, 0));
      //make sure user can enable/disable on this device explicitly:
      if (!devices.ContainsKey(KeeAutoExecExt.ThisDeviceId))
        devices[KeeAutoExecExt.ThisDeviceId] = false;
      foreach (var ifDevice in devices)
      {
        entry.Strings.Set(strUiIfDevice + ifDevice.Key, new ProtectedString(false, ifDevice.Value.ToString()));
      }
    }

    public override void PrepareForSaving(PwEntry entry)
    {
      entry.Strings.Set(PwDefs.UrlField, new ProtectedString(false, entry.Strings.ReadSafe(strUiDatabaseFile)));
      entry.Strings.Set(PwDefs.UserNameField, new ProtectedString(false, entry.Strings.ReadSafe(strUiKeyFile)));
      entry.Strings.Remove(strUiDatabaseFile);
      entry.Strings.Remove(strUiKeyFile);

      Dictionary<string, bool> devices = new Dictionary<string, bool>();
      foreach (string key in entry.Strings.GetKeys())
      {
        if (key.StartsWith(strUiIfDevice))
        {
          string device = key.Substring(strUiIfDevice.Length);
          devices[device] = entry.Strings.ReadSafe(key).Equals("true", StringComparison.OrdinalIgnoreCase);
        }
      }
      entry.Strings.Set(KeeAutoExecExt._ifDevice, new ProtectedString(false, KeeAutoExecExt.BuildIfDevice(devices)));
      foreach (string device in devices.Keys)
      {
        entry.Strings.Remove(strUiIfDevice + device);
      }

      base.PrepareForSaving(entry);


    }
  }
}